import pygame
import os
import sys
import random

from pygame.locals import *

class Menu(object):
    def __init__(self, items):
        brick_path = os.path.join("img", "brick.png")
        self.brick_texture = pygame.image.load(brick_path)
        
        click_sound_path = os.path.join("sfx", "click.ogg")
        self.click_sound = pygame.mixer.Sound(click_sound_path)
        
        self.font = pygame.font.Font(None, 50)
        self.shadow_distance = 4
        self.item_padding = 4
        self.selected = None
        
        self.credit_font = pygame.font.Font(None, 22)
        
        #items should be a list of tuples of (display name, function of button)
        self.items = items
        
        items_count = len(self.items)
        self.total_height = items_count * self.font.get_linesize()
        self.total_height += (items_count - 1) * self.item_padding
        
        self.block_randomizer = random.Random()
        
        #find the width of the widest item in the menu
        self.total_width = 0
        for item in items:
            test_render = self.font.render(str(item[0]), False, (255, 255, 255))
            self.total_width = max(self.total_width, test_render.get_width())
        
    def draw(self, screen):
        randstate = self.block_randomizer.getstate()
        
        #tiling brick pattern
        brick_rect = pygame.rect.Rect(0, 0, self.brick_texture.get_width(), self.brick_texture.get_height())
        
        bricks_h = screen.get_width() / self.brick_texture.get_width() +1
        bricks_v = screen.get_height() / self.brick_texture.get_height() +1
        for brick_x in range(bricks_h):
            for brick_y in range(bricks_v):               
                brick_rect.left = brick_x * self.brick_texture.get_width()
                brick_rect.top = brick_y * self.brick_texture.get_height()
                
                screen.blit(self.brick_texture, (brick_rect.left, brick_rect.top))
                
                #apparently filling outside the surface area crashes on some graphics chips even with clip set
                #tested on various Intel chips
                fill_rect = brick_rect.copy()
                fill_rect.width -= max(0, brick_rect.right - screen.get_width())
                fill_rect.height -= max(0, brick_rect.bottom - screen.get_height())
                
                random_val = 40 + int(self.block_randomizer.random() * 40)
                screen.fill((random_val, random_val, random_val), fill_rect, BLEND_RGBA_MULT)
        
        self.block_randomizer.setstate(randstate)
        
        #credits line
        credit_text = "A Breakout clone by Simon Priest, 2012 - do what you like with this code!"
        credit_display = self.credit_font.render(credit_text, True, (255, 255, 255))
        credit_x = screen.get_width() / 2 - credit_display.get_width() / 2
        credit_y = screen.get_height() - (self.item_padding + credit_display.get_height())
        screen.blit(credit_display, (credit_x, credit_y))
    
        item_index = 0
        
        top_y = screen.get_height() / 2 - self.total_height / 2
        
        for item in self.items:
            if self.selected == item_index:
                color = (255, 255, 255)
            else:
                color = (180, 180, 180)
        
            render_string = str(item[0])
            text = self.font.render(render_string, True, color)
            text_shadow = self.font.render(render_string, False, (20, 20, 20))
            
            text_x = screen.get_width() / 2 - text.get_width() / 2
            text_y = top_y + (item_index * (self.item_padding + self.font.get_linesize()))
            
            screen.blit(text_shadow, (text_x + self.shadow_distance, text_y + self.shadow_distance))
            screen.blit(text, (text_x, text_y))
            
            item_index += 1

    def update(self):
        pass
        
    def handle_input_event(self, event):
        pygame.mouse.set_visible(True)
        
        if event.type == MOUSEMOTION:
            self.selected = None
            
            pos = pygame.mouse.get_pos()
            screen = pygame.display.get_surface()
            
            left = screen.get_width() / 2 - self.total_width / 2
            x = pos[0] - left
            if x >= 0 and x <= self.total_width:
                top = screen.get_height() / 2 - self.total_height / 2
                y = pos[1] - top
                line = y / self.font.get_linesize()
                
                if line >= 0 and line < len(self.items):
                    self.selected = line
        elif event.type == MOUSEBUTTONDOWN:
            if self.selected != None:
                action = self.items[self.selected][1]
                action()
                
                self.click_sound.play()
        elif event.type == KEYDOWN:
            if event.key == K_ESCAPE:
                sys.exit(0)
                    